const electron = require('electron')
var fs = require("fs")
// var request = require("request");
const destdir = "celeb_pictures";const querydir="outputs"
try { fs.mkdir(destdir) } catch (e) { }
try { fs.mkdir(querydir) } catch (e) { }
// const { resolve } = require('path');
// the number is plenty now.
// do not download pictures with original resolution.
var pargs = process.argv;
pargs.shift();
pargs.shift();
// assume there is some name over the spot.
// base64 urlsafe decode.
// console.log(args)
const app = electron.app // electron module
const BrowserWindow = electron.BrowserWindow //enables UI

const gBase64 = function () {

    /**
     *  base64.ts
     *
     *  Licensed under the BSD 3-Clause License.
     *    http://opensource.org/licenses/BSD-3-Clause
     *
     *  References:
     *    http://en.wikipedia.org/wiki/Base64
     *
     * @author Dan Kogai (https://github.com/dankogai)
     */
    const version = '3.6.0';
    /**
     * @deprecated use lowercase `version`.
     */
    const VERSION = version;
    const _hasatob = typeof atob === 'function';
    const _hasbtoa = typeof btoa === 'function';
    const _hasBuffer = typeof Buffer === 'function';
    const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined;
    const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;
    const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    const b64chs = [...b64ch];
    const b64tab = ((a) => {
        let tab = {};
        a.forEach((c, i) => tab[c] = i);
        return tab;
    })(b64chs);
    const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
    const _fromCC = String.fromCharCode.bind(String);
    const _U8Afrom = typeof Uint8Array.from === 'function'
        ? Uint8Array.from.bind(Uint8Array)
        : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn));
    const _mkUriSafe = (src) => src
        .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_')
        .replace(/=+$/m, '');
    const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, '');
    /**
     * polyfill version of `btoa`
     */
    const btoaPolyfill = (bin) => {
        // console.log('polyfilled');
        let u32, c0, c1, c2, asc = '';
        const pad = bin.length % 3;
        for (let i = 0; i < bin.length;) {
            if ((c0 = bin.charCodeAt(i++)) > 255 ||
                (c1 = bin.charCodeAt(i++)) > 255 ||
                (c2 = bin.charCodeAt(i++)) > 255)
                throw new TypeError('invalid character found');
            u32 = (c0 << 16) | (c1 << 8) | c2;
            asc += b64chs[u32 >> 18 & 63]
                + b64chs[u32 >> 12 & 63]
                + b64chs[u32 >> 6 & 63]
                + b64chs[u32 & 63];
        }
        return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
    };
    /**
     * does what `window.btoa` of web browsers do.
     * @param {String} bin binary string
     * @returns {string} Base64-encoded string
     */
    const _btoa = _hasbtoa ? (bin) => btoa(bin)
        : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64')
            : btoaPolyfill;
    const _fromUint8Array = _hasBuffer
        ? (u8a) => Buffer.from(u8a).toString('base64')
        : (u8a) => {
            // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326
            const maxargs = 0x1000;
            let strs = [];
            for (let i = 0, l = u8a.length; i < l; i += maxargs) {
                strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
            }
            return _btoa(strs.join(''));
        };
    /**
     * converts a Uint8Array to a Base64 string.
     * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5
     * @returns {string} Base64 string
     */
    const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);
    // This trick is found broken https://github.com/dankogai/js-base64/issues/130
    // const utob = (src: string) => unescape(encodeURIComponent(src));
    // reverting good old fationed regexp
    const cb_utob = (c) => {
        if (c.length < 2) {
            var cc = c.charCodeAt(0);
            return cc < 0x80 ? c
                : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6))
                    + _fromCC(0x80 | (cc & 0x3f)))
                    : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))
                        + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                        + _fromCC(0x80 | (cc & 0x3f)));
        }
        else {
            var cc = 0x10000
                + (c.charCodeAt(0) - 0xD800) * 0x400
                + (c.charCodeAt(1) - 0xDC00);
            return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))
                + _fromCC(0x80 | ((cc >>> 12) & 0x3f))
                + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                + _fromCC(0x80 | (cc & 0x3f)));
        }
    };
    const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
    /**
     * @deprecated should have been internal use only.
     * @param {string} src UTF-8 string
     * @returns {string} UTF-16 string
     */
    const utob = (u) => u.replace(re_utob, cb_utob);
    //
    const _encode = _hasBuffer
        ? (s) => Buffer.from(s, 'utf8').toString('base64')
        : _TE
            ? (s) => _fromUint8Array(_TE.encode(s))
            : (s) => _btoa(utob(s));
    /**
     * converts a UTF-8-encoded string to a Base64 string.
     * @param {boolean} [urlsafe] if `true` make the result URL-safe
     * @returns {string} Base64 string
     */
    const encode = (src, urlsafe = false) => urlsafe
        ? _mkUriSafe(_encode(src))
        : _encode(src);
    /**
     * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5.
     * @returns {string} Base64 string
     */
    const encodeURI = (src) => encode(src, true);
    // This trick is found broken https://github.com/dankogai/js-base64/issues/130
    // const btou = (src: string) => decodeURIComponent(escape(src));
    // reverting good old fationed regexp
    const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
    const cb_btou = (cccc) => {
        switch (cccc.length) {
            case 4:
                var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
                    | ((0x3f & cccc.charCodeAt(1)) << 12)
                    | ((0x3f & cccc.charCodeAt(2)) << 6)
                    | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000;
                return (_fromCC((offset >>> 10) + 0xD800)
                    + _fromCC((offset & 0x3FF) + 0xDC00));
            case 3:
                return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12)
                    | ((0x3f & cccc.charCodeAt(1)) << 6)
                    | (0x3f & cccc.charCodeAt(2)));
            default:
                return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6)
                    | (0x3f & cccc.charCodeAt(1)));
        }
    };
    /**
     * @deprecated should have been internal use only.
     * @param {string} src UTF-16 string
     * @returns {string} UTF-8 string
     */
    const btou = (b) => b.replace(re_btou, cb_btou);
    /**
     * polyfill version of `atob`
     */
    const atobPolyfill = (asc) => {
        // console.log('polyfilled');
        asc = asc.replace(/\s+/g, '');
        if (!b64re.test(asc))
            throw new TypeError('malformed base64.');
        asc += '=='.slice(2 - (asc.length & 3));
        let u24, bin = '', r1, r2;
        for (let i = 0; i < asc.length;) {
            u24 = b64tab[asc.charAt(i++)] << 18
                | b64tab[asc.charAt(i++)] << 12
                | (r1 = b64tab[asc.charAt(i++)]) << 6
                | (r2 = b64tab[asc.charAt(i++)]);
            bin += r1 === 64 ? _fromCC(u24 >> 16 & 255)
                : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255)
                    : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);
        }
        return bin;
    };
    /**
     * does what `window.atob` of web browsers do.
     * @param {String} asc Base64-encoded string
     * @returns {string} binary string
     */
    const _atob = _hasatob ? (asc) => atob(_tidyB64(asc))
        : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary')
            : atobPolyfill;
    //
    const _toUint8Array = _hasBuffer
        ? (a) => _U8Afrom(Buffer.from(a, 'base64'))
        : (a) => _U8Afrom(_atob(a), c => c.charCodeAt(0));
    /**
     * converts a Base64 string to a Uint8Array.
     */
    const toUint8Array = (a) => _toUint8Array(_unURI(a));
    //
    const _decode = _hasBuffer
        ? (a) => Buffer.from(a, 'base64').toString('utf8')
        : _TD
            ? (a) => _TD.decode(_toUint8Array(a))
            : (a) => btou(_atob(a));
    const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/'));
    /**
     * converts a Base64 string to a UTF-8 string.
     * @param {String} src Base64 string.  Both normal and URL-safe are supported
     * @returns {string} UTF-8 string
     */
    const decode = (src) => _decode(_unURI(src));
    /**
     * check if a value is a valid Base64 string
     * @param {String} src a value to check
      */
    const isValid = (src) => {
        if (typeof src !== 'string')
            return false;
        const s = src.replace(/\s+/g, '').replace(/=+$/, '');
        return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s);
    };
    //
    const _noEnum = (v) => {
        return {
            value: v, enumerable: false, writable: true, configurable: true
        };
    };
    /**
     * extend String.prototype with relevant methods
     */
    const extendString = function () {
        const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body));
        _add('fromBase64', function () { return decode(this); });
        _add('toBase64', function (urlsafe) { return encode(this, urlsafe); });
        _add('toBase64URI', function () { return encode(this, true); });
        _add('toBase64URL', function () { return encode(this, true); });
        _add('toUint8Array', function () { return toUint8Array(this); });
    };
    /**
     * extend Uint8Array.prototype with relevant methods
     */
    const extendUint8Array = function () {
        const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body));
        _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); });
        _add('toBase64URI', function () { return fromUint8Array(this, true); });
        _add('toBase64URL', function () { return fromUint8Array(this, true); });
    };
    /**
     * extend Builtin prototypes with relevant methods
     */
    const extendBuiltins = () => {
        extendString();
        extendUint8Array();
    };
    const gBase64 = {
        version: version,
        VERSION: VERSION,
        atob: _atob,
        atobPolyfill: atobPolyfill,
        btoa: _btoa,
        btoaPolyfill: btoaPolyfill,
        fromBase64: decode,
        toBase64: encode,
        encode: encode,
        encodeURI: encodeURI,
        encodeURL: encodeURI,
        utob: utob,
        btou: btou,
        decode: decode,
        isValid: isValid,
        fromUint8Array: fromUint8Array,
        toUint8Array: toUint8Array,
        extendString: extendString,
        extendUint8Array: extendUint8Array,
        extendBuiltins: extendBuiltins,
    };

    //
    // export Base64 to the namespace
    //
    // ES5 is yet to have Object.assign() that may make transpilers unhappy.
    // gBase64.Base64 = Object.assign({}, gBase64);
    gBase64.Base64 = {};
    Object.keys(gBase64).forEach(k => gBase64.Base64[k] = gBase64[k]);
    return gBase64;
};

const Base64 = gBase64();
// console.log(pargs[0]);
// make request first?
// or just read from file.
function safe_b64(string) {
    // the padding problem.
    let a = string.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_"); return a;
}
function uuidv4() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

function _h() { console.log("specify exact 1 b64_urlsafe encoded query word!") }
app.on('ready', _ => {
    var mainWord = "";
    var orig = safe_b64(pargs[0]);
    if (pargs.length != 1) {
        _h();
        app.quit();
    } else {
        try {
            mainWord = Base64.decode(pargs[0]); console.log(mainWord)
        } catch (e) { console.log(e); _h(); }
    }
    // app.quit();
    mainWord = encodeURI(mainWord);
    console.log("final result:", mainWord);
    // mainWord = encodeURI(mainWord);
    // app.commandLine.hasSwitch();
    win = new BrowserWindow({
        width: 800,
        height: 600,
        show: true
    })
    var session = win.webContents.session;
    // sess.
    const cookie_path = "file:///E:/AGI/AutoUP/.confidential/bilibili_cookies_std.json";
    // // fs.readFileSync("file:///E:/AGI/AutoUP/.confidential/bilibili_cookies_std.json")
    fs.readFile(new URL(cookie_path), 'utf8', function(err,data){ 
    //     // Display the file content 
    // this is no-go. do puppeteer.
        const url = "https://message.bilibili.com/#/whisper/mid49702907";
        var cookies = JSON.parse(data)
        for (let cookie of cookies){/*console.log(cookie);*/
            var setCookie={
                url:url,
    name: cookie["name"], 
    value: cookie["value"],  
            // }
    // domain: cookie["domain"],  
            };
    // hostOnly:cookie["hostOnly"],   
    // path: cookie["path"],
    // secure: cookie["secure"],   
    // httpOnly: cookie["httpOnly"], 
    // session:cookie["session"],    
    // sameSite: cookie["sameSite"]};
    // console.log("domain",cookie["domain"])

    // var setCookie = {
    //     url: 'http://localhost',
    //     name: 'BA_HECTOR',
    //     value: 'ag8k210g840l2h0hir1fulpjv0r'
    //   };
            session.cookies.set(setCookie);
            // console.dir(session.cookies)
        }
        // const url = "https://www.baidu.com";
        const somecode = ``;
        win.loadURL(url)    
        // console.log(data); 
    }); 
    // for (let cookie of cookies){session.cookies.set(cookie)}
    // win.blur()
    // notice! page out of bound?
    // const url = "https://message.bilibili.com/#/whisper/mid49702907";
    // const url = "https://www.baidu.com";
    // const somecode = ``;
    // win.loadURL(url)    // loads this URL
    // reuse the code.
    // this is not image downloading.

    // const meta = uuidv4();

    // // var picount = 0;
    // // const maxCount = 24;
    // var contents = win.webContents;
    // // const readyState = "reponsive";
    // const readyState = "dom-ready";
    // // "did-finish-load"
    // contents.on(readyState, () => {
    //     // don't you fucking wait.
    //     session.cookies.get({})
    //     .then((cookies) => {
    //       console.log("cookie",cookies)
    //     }).catch((error) => {
    //       console.log(error)
    //     })
    //     // let's show.
    // })
    // App {
    //     _events: [Object: null prototype] {
    //       'certificate-error': [Function],
    //       'select-client-certificate': [Function],
    //       quit: [Function],
    //       'window-all-closed': [Function],
    //       ready: [Function]
    //     },
    //     _eventsCount: 5,
    //     _maxListeners: undefined,
    //     commandLine: {
    //       hasSwitch: [Function: hasSwitch],
    //       getSwitchValue: [Function: getSwitchValue],
    //       appendSwitch: [Function: appendSwitch],
    //       appendArgument: [Function: appendArgument]
    //     },
    //     _setDefaultAppPaths: [Function],
    //     [Symbol(kCapture)]: false
    //   }
    // post this shit elsewhere. enable the downloader.
    // how to execute javascript on the shit?
})
